package com.zeratul.common.event.base;

import cn.hutool.core.util.ObjectUtil;
import com.zeratul.common.core.exception.ServiceException;
import com.zeratul.common.core.utils.spring.SpringUtils;
import com.zeratul.common.event.base.serial.BaseEventSerialization;
import com.zeratul.common.event.codes.EventResultCodes;
import com.zeratul.common.event.domain.ZtEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 订阅者-处理层接口
 */
public interface BaseSubscribeHandler {

    Logger log = LoggerFactory.getLogger(BaseSubscribeHandler.class);

    /**
     * 订阅消息-数据反序列化
     */
    default <T> ZtEvent<T> deserialize(byte[] bytes) {
        BaseEventSerialization serialization = SpringUtils.getBean(BaseEventSerialization.class);
        if (ObjectUtil.isNull(serialization)) {
            throw new ServiceException(EventResultCodes.NOT_FOUND_SERIALIZER);
        }
        return serialization.deserialize(bytes);
    }

    /**
     * 订阅消息-业务处理
     */
    default <T> void doHandler(byte[] bytes) {
        ZtEvent<T> ztEvent = deserialize(bytes);
        doHandler(ztEvent);
    }

    /**
     * 订阅消息-业务处理
     */
    default <T> void doHandler(ZtEvent<T> ztEvent) {
        try {
            //调用服务层对象处理消息
            BaseSubscribeServer subscribeServer = SpringUtils.getBean(BaseSubscribeServer.class);
            if (ObjectUtil.isNotNull(subscribeServer)) {
                subscribeServer.eventHandler(ztEvent);
            }

            //消息确认
            ack(ztEvent);
        } catch (Exception e) {
            log.error("【事件总线】订阅消息失败！", e);
            //消息拒绝
            reject(ztEvent);
        }
    }

    /**
     * 消息确认
     */
    default <T> void ack(ZtEvent<T> ztEvent) {
    }

    /**
     * 消息拒绝
     */
    default <T> void reject(ZtEvent<T> ztEvent) {
    }
}
